import { Controller, Get } from '@nestjs/common';
import { HealthCheck, HealthCheckService } from '@nestjs/terminus';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { PrismaService } from '../database/prisma.service';
import { ConfigService } from '@nestjs/config';

/**
 * 健康检查控制器
 * 零隐患MFIS规范 - 解决隐患：#4 熔断器监控
 */
@ApiTags('health')
@Controller('health')
export class HealthController {
  constructor(
    private readonly health: HealthCheckService,
    private readonly prisma: PrismaService,
    private readonly configService: ConfigService,
  ) {}

  @Get()
  @HealthCheck()
  @ApiOperation({ summary: '系统健康检查' })
  @ApiResponse({
    status: 200,
    description: '系统健康状态',
    schema: {
      type: 'object',
      properties: {
        status: { type: 'string', enum: ['ok', 'error'] },
        info: { type: 'object' },
        error: { type: 'object' },
        details: { type: 'object' },
      },
    },
  })
  async check() {
    return this.health.check([
      async () => {
        try {
          await this.prisma.$queryRaw`SELECT 1`;
          return {
            database: {
              status: 'up',
              timestamp: new Date().toISOString(),
            },
          };
        } catch (error) {
          return {
            database: {
              status: 'down',
              error: error.message,
              timestamp: new Date().toISOString(),
            },
          };
        }
      },
      async () => {
        return {
          memory: {
            status: 'up',
            usage: process.memoryUsage(),
            timestamp: new Date().toISOString(),
          },
        };
      },
      async () => {
        return {
          uptime: {
            status: 'up',
            seconds: process.uptime(),
            timestamp: new Date().toISOString(),
          },
        };
      },
    ]);
  }

  @Get('detailed')
  @ApiOperation({ summary: '详细健康检查' })
  async detailedCheck() {
    const startTime = Date.now();

    try {
      const [dbHealth, memoryInfo, systemInfo] = await Promise.all([
        this.prisma.healthCheck(),
        this.getMemoryInfo(),
        this.getSystemInfo(),
      ]);

      const responseTime = Date.now() - startTime;

      return {
        status: 'healthy',
        timestamp: new Date().toISOString(),
        response_time_ms: responseTime,
        services: {
          database: dbHealth,
          memory: memoryInfo,
          system: systemInfo,
        },
        config: {
          node_env: this.configService.get<string>('NODE_ENV'),
          app_name: this.configService.get<string>('APP_NAME'),
          app_version: this.configService.get<string>('APP_VERSION'),
        },
      };

    } catch (error) {
      return {
        status: 'unhealthy',
        timestamp: new Date().toISOString(),
        error: error.message,
        response_time_ms: Date.now() - startTime,
      };
    }
  }

  private async getMemoryInfo() {
    const memUsage = process.memoryUsage();
    const totalMem = require('os').totalmem();
    const freeMem = require('os').freemem();

    return {
      status: 'healthy',
      usage: {
        rss: Math.round(memUsage.rss / 1024 / 1024), // MB
        heap_total: Math.round(memUsage.heapTotal / 1024 / 1024), // MB
        heap_used: Math.round(memUsage.heapUsed / 1024 / 1024), // MB
        external: Math.round(memUsage.external / 1024 / 1024), // MB
      },
      system: {
        total: Math.round(totalMem / 1024 / 1024), // MB
        free: Math.round(freeMem / 1024 / 1024), // MB
        used: Math.round((totalMem - freeMem) / 1024 / 1024), // MB
      },
      timestamp: new Date().toISOString(),
    };
  }

  private async getSystemInfo() {
    const os = require('os');
    return {
      status: 'healthy',
      platform: os.platform(),
      arch: os.arch(),
      node_version: process.version,
      uptime: Math.round(process.uptime()),
      load_average: os.loadavg(),
      cpu_count: os.cpus().length,
      timestamp: new Date().toISOString(),
    };
  }
}